/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package SRDThread;

import SRDException.SRDException;
import commands.dmonComandos;
import commands.drepComandos;
import components.drep;
import java.net.*;
import java.io.*;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import protocol.SRDProtocol;

/**
 *
 * @author ylopez
 */
public class SRDThread extends Thread {

    private Socket socket = null;
    private String hostDmon = null;
    private int portDmon = 0;
    private String directory = null;
    private boolean isPrincipal = false;
    private InetAddress ownIP = null;
    private List users;
    private String from = null;
    private int[] count = new int[]{0,0,0};
    PrintWriter out;
    BufferedReader in;
    SRDThread anotherThread = null;

    public SRDThread(Socket socket){
        this.socket = socket;
    }
    
    public SRDThread(Socket socket, String hostDmon, int portDmon, String directory, boolean isPrincipal, InetAddress ownIP, List users, String from, int[] count, PrintWriter out, BufferedReader in, SRDThread anotherThread){
        this.socket = socket;
        this.hostDmon = hostDmon;
        this.portDmon = portDmon;
        this.directory = directory;
        this.isPrincipal = isPrincipal;
        this.ownIP = ownIP;
        this.users = users;
        this.from = from;
        this.count = count;
        this.out = out;
        this.in = in;
        this.anotherThread = anotherThread;
    }

    public void setSocket(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run(){
        try {
            if (this.isPrincipal == true && this.from.equals("drep")) {
                String userName = System.getProperty("user.name");
                System.out.println("Escriba Bye para salir");
                System.out.print(userName + "$> ");
                BufferedReader stdIn = null;
                stdIn = new BufferedReader(new InputStreamReader(System.in));
                String[] commandLine;
                String[] resoults;
                String fromUser;
                try {
                    fromUser = stdIn.readLine();
                    while (fromUser != null) {
                        commandLine = fromUser.split(" ");
                        if (commandLine[0].equals("ldir")) {
                            resoults = drepComandos.ldir(this.directory);
                            drepComandos.printResoults("ldir", resoults);
                        } else if (commandLine[0].equals("cat")) {
                            drepComandos.cat(commandLine[1]);
                        } else if (commandLine[0].equals("Bye")) {
                            drepComandos.disconnect(this.out, this.in, this.anotherThread);
                            break;
                        } else {
                            SRDException srde = new SRDException("Comando: " + fromUser
                                    + " invalido.");
                            srde.printException();
                        }
                        System.out.print(userName + "$> ");
                        fromUser = stdIn.readLine();
                    }
                } catch (IOException ex) {
                    Logger.getLogger(drep.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else if (this.isPrincipal == true && this.from.equals("dmon")) {
                String userName = System.getProperty("user.name");
                System.out.println("Escriba Bye para salir");
                System.out.print(userName + "$> ");
                BufferedReader stdIn = null;
                stdIn = new BufferedReader(new InputStreamReader(System.in));
                String[] commandLine;
                String[] resoults;
                String fromUser;
                try {
                    fromUser = stdIn.readLine();
                    while (fromUser != null) {
                        commandLine = fromUser.split(" ");
                        if (commandLine[0].equals("tuser")) {
                            resoults = dmonComandos.tuser(this.users);
                            dmonComandos.printResoults("tuser", resoults);
                        } else if (commandLine[0].equals("nops")) {
                            resoults = dmonComandos.nops(this.count);
                            dmonComandos.printResoults("nops", resoults);
                        } else if (commandLine[0].equals("Bye")) {
                            System.exit(1);
                        } else {
                            SRDException srde = new SRDException("Comando: " + fromUser
                                    + " invalido.");
                            srde.printException();
                        }
                        System.out.print(userName + "$> ");
                        fromUser = stdIn.readLine();
                    }
                } catch (IOException ex) {
                    Logger.getLogger(drep.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else if (this.isPrincipal == false && this.from.equals("dmon")) {
                PrintWriter outDrep = new PrintWriter(this.socket.getOutputStream(), true);
                BufferedReader inDrep = new BufferedReader(
                                        new InputStreamReader(
                                        this.socket.getInputStream()));

                String messageFromRep = null;

                SRDProtocol srdpIn = new SRDProtocol();
                SRDProtocol srdpOut = null;
                String[] resoult;

                while ((messageFromRep = inDrep.readLine()) != null) {
                    srdpIn.setMessage(messageFromRep);

                    if(srdpIn.getMessageAction().equals("connection")){
                        resoult = srdpIn.processMessage();

                        for (int i = 0; i < resoult.length; i += 2) {
                            this.users.add(resoult[i] + "  " + resoult[i+1]);
                        }
                        resoult = new String[]{"OK"};
                        srdpOut = new SRDProtocol("replyConnection", resoult);
                        outDrep.println(srdpOut.getMessage());
                    }

                    if(srdpIn.getMessageAction().equals("drepConnection")){
                        this.count[0]++;
                        resoult = new String[]{"OK"};
                        srdpOut = new SRDProtocol("replyDrepConnection", resoult);
                        outDrep.println(srdpOut.getMessage());
                    }

                    if (srdpIn.getMessageAction().equals("replyReplyDrepConnection")) {
                        //TODO Skip
                    }

                    if (srdpIn.getMessageAction().equals("tuser")) {
                        resoult = dmonComandos.tuser(this.users);
                        srdpOut = new SRDProtocol("replyTuser", resoult);
                        outDrep.println(srdpOut.getMessage());
                    }

                    if (srdpIn.getMessageAction().equals("nrep")) {
                        resoult = new String[]{String.valueOf(this.count[0])};
                        srdpOut = new SRDProtocol("replyNrep", resoult);
                        outDrep.println(srdpOut.getMessage());
                    }

                    if (srdpIn.getMessageAction().equals("drepDisconnect")) {
                        resoult = new String[]{String.valueOf(this.count[0])};
                        this.count[0]--;
                    }

                    if (srdpIn.getMessageAction().equals("disconnect")) {
                        resoult = srdpIn.processMessage();
                        dmonComandos.dropUser(resoult, this.users);
                    }

                    if (srdpIn.getMessageAction().equals("sube")) {
                        this.count[1]++;
                    }

                    if (srdpIn.getMessageAction().equals("baja")) {
                        this.count[2]++;
                    }
                }
                outDrep.close();
                inDrep.close();
                socket.close();

            }else {
                PrintWriter outDclip = new PrintWriter(this.socket.getOutputStream(), true);
                BufferedReader inDclip = new BufferedReader(
                                        new InputStreamReader(
                                        this.socket.getInputStream()));

                String messageFromClient = null;

                SRDProtocol srdpIn = new SRDProtocol();
                SRDProtocol srdpOut = null;
                String[] resoult;

                while ((messageFromClient = inDclip.readLine()) != null) {
                    srdpIn.setMessage(messageFromClient);

                    if(srdpIn.getMessageAction().equals("rdir")){
                        resoult = drepComandos.ldir(this.directory);
                        srdpOut = new SRDProtocol("replyRdir", resoult);
                        outDclip.println(srdpOut.getMessage());
                    }

                    if(srdpIn.getMessageAction().equals("sube")){
                        this.out.println(srdpIn.getMessage());
                        resoult = drepComandos.saveFile(srdpIn.getMessage(), this.directory, this.socket);
                        srdpOut = new SRDProtocol("replySube", resoult);
                        outDclip.println(srdpOut.getMessage());
                    }

                    if (srdpIn.getMessageAction().equals("existFile")) {
                        resoult = drepComandos.existFile(srdpIn, this.directory);
                        srdpOut = new SRDProtocol("replyExistFile", resoult);
                        outDclip.println(srdpOut.getMessage());
                    }

                    if(srdpIn.getMessageAction().equals("baja")){
                        drepComandos.sendFile(srdpIn.getMessage(), this.directory, this.socket);
                        this.out.println(srdpIn.getMessage());
                    }

                    if(srdpIn.getMessageAction().equals("connection")){
                        String messageFromDmon = null;
                        this.out.println(srdpIn.getMessage());
                        while (true) {
                            try {
                                if ((messageFromDmon = this.in.readLine()) != null) {
                                    resoult = new String[]{"OK"};
                                    srdpOut = new SRDProtocol("replyConnection", resoult);
                                    break;
                                }
                            } catch (IOException ex) {
                                Logger.getLogger(drepComandos.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        outDclip.println(srdpOut.getMessage());
                    }

                    if (srdpIn.getMessageAction().equals("replyReplyConnection")) {
                        //TODO Skip
                    }

                    if (srdpIn.getMessageAction().equals("tuser")) {
                        String messageFromDmon = null;
                        out.println(srdpIn.getMessage());
                        while (true) {
                            try {
                                if ((messageFromDmon = this.in.readLine()) != null) {
                                    srdpOut = new SRDProtocol();
                                    srdpOut.setMessage(messageFromDmon);
                                    break;
                                }
                            } catch (IOException ex) {
                                Logger.getLogger(drepComandos.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        outDclip.println(srdpOut.getMessage());
                    }

                    if (srdpIn.getMessageAction().equals("nrep")) {
                        String messageFromDmon = null;
                        this.out.println(srdpIn.getMessage());
                        while (true) {
                            try {
                                if ((messageFromDmon = this.in.readLine()) != null) {
                                    srdpOut = new SRDProtocol();
                                    srdpOut.setMessage(messageFromDmon);
                                    break;
                                }
                            } catch (IOException ex) {
                                Logger.getLogger(drepComandos.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        outDclip.println(srdpOut.getMessage());
                    }

                    if (srdpIn.getMessageAction().equals("disconnect")) {
                        this.out.println(srdpIn.getMessage());
                    }
                }
                outDclip.close();
                inDclip.close();
                socket.close();
            }

	} catch (IOException e) {
	    e.printStackTrace();
	}
    }
}
